package com.todod.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.todod.common.util.CheckExcelData;
import com.todod.common.util.ExcelReaderXlsx;
import com.todod.common.util.SnowflakeIdGenerator;
import com.todod.entity.ErrorExcelMsg;
import com.todod.entity.QueryEntry;
import com.todod.entity.ReqCatalog;
import com.todod.mapper.CatalogDetailMapper;
import com.todod.mapper.CatalogManageMapper;
import com.todod.model.CatalogDetail;
import com.todod.model.CatalogManage;
import com.todod.model.Dict;
import com.todod.model.User;
import com.todod.service.ICatalogManageService;
import com.todod.service.IDictService;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author dyl
 * @date 2022-09-05
 */
@Service
@Transactional
public class CatalogManageServiceImpl extends ServiceImpl<CatalogManageMapper, CatalogManage>
		implements ICatalogManageService {
	@Autowired
	private CatalogManageMapper catalogManageMapper;
	@Autowired
	private CatalogDetailMapper catalogDetailMapper;
	@Autowired
	private IDictService iDictService;

	@Override
	public IPage<CatalogManage> getListPage(QueryEntry queryEntry) {

		Page<CatalogManage> page = new Page<>(queryEntry.getPage(), queryEntry.getLimit());
		IPage<CatalogManage> iPage = catalogManageMapper.getListPage(page, queryEntry);

		return iPage;
	}

	@Override
	public void saveData(Long _userId, CatalogManage catalogManage) {

		catalogManage.setId(SnowflakeIdGenerator.getId());

		catalogManage.setState("1");
		catalogManage.setCreatetimeTi(LocalDateTime.now());
		catalogManage.setCreateuserId(_userId);
		catalogManageMapper.insert(catalogManage);
	}

	@Override
	public void editData(Long _userId, CatalogManage catalogManage) {

		catalogManage.setModifytimeTi(LocalDateTime.now());
		catalogManage.setModifyuserId(_userId);
		catalogManageMapper.updateById(catalogManage);
	}

	@Override
	public void copyData(Long _userId, ReqCatalog reqCatalog) {

		CatalogManage catalogManage = reqCatalog.getData();

		Long classifyId = reqCatalog.getData1();

		catalogManage.setId(SnowflakeIdGenerator.getId());

		catalogManage.setState("1");
		catalogManage.setCreatetimeTi(LocalDateTime.now());
		catalogManage.setCreateuserId(_userId);

		QueryWrapper<CatalogDetail> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("cmd_classify_id", classifyId);
		queryWrapper.orderByAsc("cmd_sort_num");

		List<CatalogDetail> list = catalogDetailMapper.selectList(queryWrapper);

		// 组装成父子的树形结构
		// 2.1找到所有的一级分类
		List<CatalogDetail> level1Menus = list.stream().filter(catalogDetail -> catalogDetail.getParentId() == 1)
				.map((menu) -> {
					menu.setChildren(getChildrens(menu, list));
					return menu;
				}).sorted((menu1, menu2) -> {
					return (menu1.getSortNum() == null ? 0 : menu1.getSortNum())
							- (menu2.getSortNum() == null ? 0 : menu2.getSortNum());
				}).collect(Collectors.toList());

		for (CatalogDetail catalogDetail : level1Menus) {
			CatalogDetail catalogDetail1 = new CatalogDetail();
			BeanUtils.copyProperties(catalogDetail, catalogDetail1);

			catalogDetail1.setId(SnowflakeIdGenerator.getId());

			catalogDetail1.setClassifyId(catalogManage.getId());
			catalogDetail1.setState("1");
			catalogDetail1.setCreatetimeTi(LocalDateTime.now());
			catalogDetail1.setCreateuserId(_userId);
			if (catalogDetail.getChildren() != null && catalogDetail.getChildren().size() > 0) {
				setChildrens(_userId, catalogDetail, catalogDetail1, catalogManage.getId());
			}
			catalogDetailMapper.insert(catalogDetail1);
		}

		catalogManageMapper.insert(catalogManage);
	}

	// 获取自己菜单
	private List<CatalogDetail> getChildrens(CatalogDetail root, List<CatalogDetail> all) {
		List<CatalogDetail> children = all.stream().filter(catalogDetail -> {
			return catalogDetail.getParentId().equals(root.getId());
		}).map(catalogDetail -> {
			// 1.找到子菜单
			catalogDetail.setChildren(getChildrens(catalogDetail, all));
			return catalogDetail;
		}).sorted((menu1, menu2) -> {
			// 2.菜单的顺序
			return (menu1.getSortNum() == null ? 0 : menu1.getSortNum())
					- (menu2.getSortNum() == null ? 0 : menu2.getSortNum());
		}).collect(Collectors.toList());
		return children;
	}

	// 获取自己菜单
	/**
	 * 
	 * @param _userId
	 * @param catalogDetail
	 * @param parentId
	 * @param classifyId
	 */
	private void setChildrens(Long _userId, CatalogDetail catalogDetail, CatalogDetail catalogDetail1,
			Long classifyId) {
		List<CatalogDetail> list01 = catalogDetail.getChildren();
		for (CatalogDetail catalogDetail01 : list01) {
			CatalogDetail catalogDetail02 = new CatalogDetail();
			BeanUtils.copyProperties(catalogDetail01, catalogDetail02);

			catalogDetail02.setId(SnowflakeIdGenerator.getId());

			if (catalogDetail1.getLevels() != null) {
				catalogDetail02.setLevels(catalogDetail1.getLevels() + catalogDetail1.getId() + ";");
			} else {
				catalogDetail02.setLevels(catalogDetail1.getId() + ";");
			}

			catalogDetail02.setClassifyId(classifyId);
			catalogDetail02.setParentId(catalogDetail1.getId());
			catalogDetail02.setState("1");
			catalogDetail02.setCreatetimeTi(LocalDateTime.now());
			catalogDetail02.setCreateuserId(_userId);

			if (catalogDetail01.getChildren() != null && catalogDetail01.getChildren().size() > 0) {
				setChildrens(_userId, catalogDetail01, catalogDetail02, classifyId);
			}

			catalogDetailMapper.insert(catalogDetail02);
		}
	}

	@Override
	public void saveUploadTbData(HttpServletRequest request, InputStream is, User user, Long classifyId)
			throws Exception {

		ExcelReaderXlsx readExcel = new ExcelReaderXlsx(is);
		try {
			readExcel.open();

			List<CatalogDetail> dataList = new ArrayList<CatalogDetail>();// 数据
			List<ErrorExcelMsg> erroeList = new ArrayList<ErrorExcelMsg>();// 错误数据

			List<String> names = new ArrayList<>();

			int sheetNum = 0; // sheet页数

			readExcel.setSheetNum(sheetNum); // 设置读取索引为sheetCount的工作表
			int ronNum = readExcel.getRowCount(); // 总行数

			String sheetName = readExcel.getSheetName();

			List<Dict> iDictList1 = iDictService.getListByParentCode("YW_CATALOG_TYPE");

			// 纵向获取数据
			for (int rowCount = 1; rowCount <= ronNum; rowCount++) {
				// A 一级目录
				String catalog01 = readExcel.readStringExcelCell(sheetNum, rowCount, 0);
				// B 二级目录
				String catalog02 = readExcel.readStringExcelCell(sheetNum, rowCount, 1);
				// C 三级目录
				String catalog03 = readExcel.readStringExcelCell(sheetNum, rowCount, 2);
				// D 目录类型
				String typeName = readExcel.readStringExcelCell(sheetNum, rowCount, 3);
				// E 序号
				String sortNum = readExcel.readStringExcelCellWithXiaoShu(sheetNum, rowCount, 4);

				ErrorExcelMsg excelMsg = CheckExcelData.checkNull(sheetName, rowCount, "A", catalog01, "一级目录");
				if (excelMsg != null) {
					throw new Exception(excelMsg.getErrorMsg());
				}

				excelMsg = CheckExcelData.checkNull(sheetName, rowCount, "B", catalog02, "二级目录");
				if (excelMsg != null) {
					throw new Exception(excelMsg.getErrorMsg());
				}

				excelMsg = CheckExcelData.checkDictName(sheetName, rowCount, "D", typeName, iDictList1, "目录类型");
				if (excelMsg != null) {
					throw new Exception(excelMsg.getErrorMsg());
				}

				excelMsg = CheckExcelData.checkNull(sheetName, rowCount, "E", sortNum, "序号");
				if (excelMsg != null) {
					throw new Exception(excelMsg.getErrorMsg());
				}

				if (!names.contains(catalog01)) {
					names.add(catalog01);
				}

				CatalogDetail catalogDetail = new CatalogDetail();

				Dict ajlxDict = iDictService.getDictByPcodeAndName("YW_CATALOG_TYPE", typeName);

				catalogDetail.setCatalog01(catalog01);
				catalogDetail.setCatalog02(catalog02);
				if (catalog03 != null && !catalog03.equalsIgnoreCase("") && !catalog03.equalsIgnoreCase("null")
						&& StringUtils.isNotBlank(catalog03)) {
					catalogDetail.setCatalog03(catalog03);
				}
				catalogDetail.setFlag(ajlxDict.getCode());

				dataList.add(catalogDetail);
			}

			if (erroeList.size() == 0 && dataList.size() == 0) {// 空模板
				ErrorExcelMsg errorExcelMsg = new ErrorExcelMsg("模板无数据");
				throw new Exception(errorExcelMsg.getErrorMsg());
			}

			if (erroeList.size() == 0) { // 保存数据
				saveDataList(user, dataList, names, classifyId);
			} else {
				return;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * @Title: saveDataList
	 * @Description:保存数据
	 * @author dyl
	 * @date 2020-04-16
	 * @param user
	 * @param dataList
	 * @param names
	 * @param status
	 */
	public void saveDataList(User user, List<CatalogDetail> dataList, List<String> names, Long classifyId) {

		for (int i = 0; i < names.size(); i++) {

			CatalogDetail catalogDetail = new CatalogDetail();

			catalogDetail.setId(SnowflakeIdGenerator.getId());

			catalogDetail.setTypeName(names.get(i));
			catalogDetail.setParentId(1l);
			catalogDetail.setSortNum(i);
			catalogDetail.setClassifyId(classifyId);
			catalogDetail.setLevels("");
			catalogDetail.setFlag("1");
			catalogDetail.setState("1");
			catalogDetail.setCreatetimeTi(LocalDateTime.now());
			catalogDetail.setCreateuserId(user.getId());

			setChildrens2(user.getId(), catalogDetail, dataList, classifyId);

			catalogDetailMapper.insert(catalogDetail);
		}
	}

	private void setChildrens2(Long userId, CatalogDetail catalogDetail, List<CatalogDetail> dataList,
			Long classifyId) {
		int i = 0;
		List<String> names = new ArrayList<>();
		for (int j = 0; j < dataList.size(); j++) {
			if (dataList.get(j).getCatalog01().equalsIgnoreCase(catalogDetail.getTypeName())) {

				if (!names.contains(dataList.get(j).getCatalog02())) {
					names.add(dataList.get(j).getCatalog02());

					CatalogDetail catalogDetail1 = new CatalogDetail();

					catalogDetail1.setId(SnowflakeIdGenerator.getId());

					catalogDetail1.setTypeName(dataList.get(j).getCatalog02());
					catalogDetail1.setParentId(catalogDetail.getId());
					catalogDetail1.setSortNum(i);
					catalogDetail1.setClassifyId(classifyId);
					// 源数据
					if (catalogDetail.getLevels() != null) {
						catalogDetail1.setLevels(catalogDetail.getLevels() + catalogDetail.getId() + ";");
					} else {
						catalogDetail1.setLevels(catalogDetail.getId() + ";");
					}

					catalogDetail1.setFlag(dataList.get(j).getFlag());
					catalogDetail1.setState("1");
					catalogDetail1.setCreatetimeTi(LocalDateTime.now());
					catalogDetail1.setCreateuserId(userId);

					i++;

					setChildrens3(userId, catalogDetail, catalogDetail1, dataList, classifyId);

					catalogDetailMapper.insert(catalogDetail1);
				}
			}
		}
	}

	private void setChildrens3(Long userId, CatalogDetail catalogDetail, CatalogDetail catalogDetail1,
			List<CatalogDetail> dataList, Long classifyId) {
		int i = 0;
		for (int j = 0; j < dataList.size(); j++) {
			if (dataList.get(j).getCatalog01().equalsIgnoreCase(catalogDetail.getTypeName())
					&& dataList.get(j).getCatalog02().equalsIgnoreCase(catalogDetail1.getTypeName())) {

				if (dataList.get(j).getCatalog03() != null && StringUtils.isNotBlank(dataList.get(j).getCatalog03())) {
					CatalogDetail catalogDetail2 = new CatalogDetail();

					catalogDetail2.setId(SnowflakeIdGenerator.getId());

					catalogDetail2.setTypeName(dataList.get(j).getCatalog03());
					catalogDetail2.setParentId(catalogDetail1.getId());
					catalogDetail2.setSortNum(i);
					catalogDetail2.setClassifyId(classifyId);
					// 源数据
					if (catalogDetail.getLevels() != null) {
						catalogDetail2.setLevels(catalogDetail1.getLevels() + catalogDetail1.getId() + ";");
					} else {
						catalogDetail2.setLevels(catalogDetail1.getId() + ";");
					}

					catalogDetail2.setFlag(dataList.get(j).getFlag());
					catalogDetail2.setState("1");
					catalogDetail2.setCreatetimeTi(LocalDateTime.now());
					catalogDetail2.setCreateuserId(userId);

					i++;

					catalogDetailMapper.insert(catalogDetail2);
				}
			}
		}
	}

	@Override
	public List<CatalogManage> getListByCode(String code) {

		QueryWrapper<CatalogManage> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("cm_code", code);
		queryWrapper.eq("cm_state", "1");

		List<CatalogManage> list = catalogManageMapper.selectList(queryWrapper);
		return list;
	}

	@Override
	public void updateState(Long _userId, Long code, String status) {
		CatalogManage catalog = catalogManageMapper.selectById(code);

		catalog.setState(status);
		catalog.setModifyuserId(_userId);
		catalog.setModifytimeTi(LocalDateTime.now());
		catalogManageMapper.updateById(catalog);
	}

}
